package com.example.demo.controller;

import com.example.demo.code.CustomStatusCode;
import com.example.demo.converter.PersonalInfoConverter;
import com.example.demo.error.ApiResponse;
import com.example.demo.exceptions.RecordExistsException;
import com.example.demo.exceptions.RecordNotFoundException;
import com.example.demo.model.CheckRole;
import com.example.demo.model.PersonalInfo;
import com.example.demo.service.PersonalInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/api/personalinfo")
public class PersonalInfoController {

    @Autowired
    private PersonalInfoService personalInfoService;
    @Autowired
    private PersonalInfoConverter personalInfoConverter;

    @PostMapping
    @CheckRole("ROLE_ADMIN")
    public ResponseEntity<ApiResponse> addPersonalInfo(@RequestBody PersonalInfo personalInfo) {
        if (personalInfoService.checkIfPersonalInfoExists(personalInfo.getName(), personalInfo.getPhoneNumber())) {
            throw new RecordExistsException("Record already exists.");
        }
        PersonalInfo createdInfo = personalInfoService.createPersonalInfo(personalInfo);
        return ResponseEntity.ok(new ApiResponse(CustomStatusCode.RESOURCE_CREATED, createdInfo, 1));
    }

    @PutMapping("/{id}")
    @CheckRole("ROLE_ADMIN")
    public ResponseEntity<ApiResponse> updatePersonalInfo(@PathVariable int id, @RequestBody PersonalInfo updatedInfo) {
        PersonalInfo info = personalInfoService.updatePersonalInfo(id, updatedInfo);
        if (info != null) {
            return ResponseEntity.ok(new ApiResponse(CustomStatusCode.RESOURCE_UPDATED, info, 1));
        } else {
            throw new RecordNotFoundException("Record not found.");
        }
    }

    @DeleteMapping("/{id}")
    @CheckRole("ROLE_ADMIN")
    public ResponseEntity<ApiResponse> removePersonalInfo(@PathVariable int id) {
        PersonalInfo deletedInfo = personalInfoService.getPersonalInfoById(id).orElseThrow(() -> new RecordNotFoundException("Record not found."));
        personalInfoService.deletePersonalInfo(id);
        return ResponseEntity.ok(new ApiResponse(CustomStatusCode.RESOURCE_DELETED, deletedInfo, 1));
    }

    @GetMapping("/{id}")
    @CheckRole({"ROLE_USER","ROLE_ADMIN"})
    public ResponseEntity<ApiResponse> getPersonalInfo(@PathVariable int id) {
        Optional<PersonalInfo> info = personalInfoService.getPersonalInfoById(id);
        if (info.isPresent()) {
            PersonalInfo maskedInfo = (PersonalInfo) personalInfoConverter.convert(info.get());
            return ResponseEntity.ok(new ApiResponse(CustomStatusCode.RESOURCE_QUERY, maskedInfo, 1));
        } else {
            throw new RecordNotFoundException("Record not found.");
        }
    }

    @GetMapping("/all")
    @CheckRole("ROLE_ADMIN")
    public ResponseEntity<ApiResponse> getAllPersonalInfo() {
        List<PersonalInfo> allInfo = personalInfoService.getAllPersonalInfo();
        if (!allInfo.isEmpty()) {
            List<PersonalInfo> maskedAllInfo = new ArrayList<>();
            for (PersonalInfo info : allInfo) {
                PersonalInfo maskedInfo = (PersonalInfo) personalInfoConverter.convert(info);
                maskedAllInfo.add(maskedInfo);
            }
            return ResponseEntity.ok(new ApiResponse(CustomStatusCode.RESOURCE_QUERY_ALL, maskedAllInfo, allInfo.size()));
        } else {
            throw new RecordNotFoundException("No records found.");
        }
    }
}